﻿using AccidentalNoise;
using Microsoft.Xna.Framework;

namespace block_explorer
{
    class AccidentalBuilder : IMapBuilder
    {
        ModuleBase mNoise;
        ModuleBase mContentNoise;

        public AccidentalBuilder()
        {
            BuildNoiseChain();
        }

        public Block GetBlock(Vector3 worldPosition)
        {
            double density = mNoise.Get(worldPosition.X, worldPosition.Y, worldPosition.Z);
            if (density > 0.5)
            {
                double type = mContentNoise.Get(worldPosition.X, worldPosition.Y, worldPosition.Z);
                if (type > 0.5)
                    return new Block(Block.ContentType.DIRT);
                else
                    return new Block(Block.ContentType.STONE);
            }
            else
            {
                return new Block(Block.ContentType.AIR);
            }
        }

        private void BuildNoiseChain()
        {
            Fractal ridges = new Fractal(FractalType.FBM, BasisTypes.SIMPLEX, InterpTypes.LINEAR, 6, 0.005, 1234);
            ScaleDomain heightmap = new ScaleDomain(ridges, 1.0, 0.0, 1.0);
            ScaleOffset scaledHeightmap = new ScaleOffset(heightmap, 20.0, 0.0);
            Gradient density = new Gradient(0, 0, 80, 0, 0, 0);
            TranslatedDomain hillDensity = new TranslatedDomain(density, null, scaledHeightmap, null);

            Fractal v = new Fractal(FractalType.FBM, BasisTypes.SIMPLEX, InterpTypes.LINEAR, 1, 0.01, 9876);
            ScaleDomain s = new ScaleDomain(v, 1.0, 0.0, 1.0);
            ScaleOffset i = new ScaleOffset(s, 20.0, 0.0);
            TranslatedDomain adjustedHillDensity = new TranslatedDomain(hillDensity, null, i, null);

            Fractal result1 = new Fractal(FractalType.RIDGEDMULTI, BasisTypes.SIMPLEX, InterpTypes.LINEAR, 1, 0.02, 9876);
            Fractal result2 = new Fractal(FractalType.RIDGEDMULTI, BasisTypes.SIMPLEX, InterpTypes.LINEAR, 1, 0.02, 6789);
            Combiner result = new Combiner(CombinerTypes.MULT, result1, result2);

            ScaleOffset sc = new ScaleOffset(hillDensity, 0.5, 0.0);
            Combiner combinedDensity = new Combiner(CombinerTypes.MULT, sc, result);

            Select caves = new Select(combinedDensity, 1.0, 0.0, 0.2, 0.0);

            //mNoise = caves;

            mNoise = new Combiner(CombinerTypes.MULT, hillDensity, caves);

            //mNoise = hillDensity;

            mContentNoise = new Fractal(FractalType.RIDGEDMULTI, BasisTypes.SIMPLEX, InterpTypes.LINEAR, 1, 0.03, 4321);
        }
    }
}
